package com.gossip.manager;
import java.io.*;
import java.net.*;
import com.gossip.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MemberListener extends Thread implements Runnable {
	private int _port;
    private String _line,_input;
    private AtomicBoolean _gossipServiceRunning;
    private GossipMember _me;
    private ArrayList<GossipMember> _members;
    public MemberListener(int port, GossipMember me, ArrayList<GossipMember> members ) {
      this._port = me.getPort();
      this._me = me;
      this._members = members;
      this._gossipServiceRunning = new AtomicBoolean(true);
    }
    
    public void shutdown() {
		_gossipServiceRunning.set(false);
	}
    
	public void run() {
		GossipService.info("The MemberListener process is started.");
		ServerSocket listener = null;
		try {
			listener = new ServerSocket(_port);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		Socket server = null;
		// keep the main thread around
		while(_gossipServiceRunning.get()) {
			if(server==null)
			{
				_input = "";
				try
				{
					GossipService.info("start listerning"); 
					server = listener.accept();
					GossipService.info("get message"); 
					DataInputStream in = new DataInputStream (server.getInputStream());
					 while((_line = in.readLine()) != null) {
				            _input=_input + _line;
				          }
					 server.close();
					 System.out.println("Receive sync info: " + _input);
				}
				catch (IOException ioe) 
				{
			          System.out.println("IOException on socket listen: " + ioe);
			          ioe.printStackTrace();
			    }
				server = null;
				if(_input!="")
				try
				{
					ArrayList<GossipMember> syncMembers = GetMemberListFromStr(_input);
					MemberManager.MergeList(_me, _members, syncMembers);
				} 
				catch (JSONException e) 
				{
					GossipService.error("exception during JSON parsing");
					e.printStackTrace();
				}
			}
			else
			{
				server = null;
				GossipService.error("server is not null by some reason, set it as null");
			}
			
		}
	}
    

    private ArrayList<GossipMember> GetMemberListFromStr(String strMembers) throws JSONException
    {
    	StringBuffer buffer = new StringBuffer(strMembers);
    	ArrayList<GossipMember> members = new ArrayList<GossipMember>();
    	ArrayList<Integer> memberIds = new ArrayList<Integer>();
    	JSONArray arr = new JSONArray(buffer.toString());
    	for(int i=0;i<arr.length();i++)
    	{
    		JSONObject obj = arr.getJSONObject(i);
    		int memberId = obj.getInt("memberId");
    		if(!memberIds.contains(memberId))
    		    memberIds.add(memberId);
    		else
    			continue;
    		RemoteGossipMember member = new RemoteGossipMember(obj.getString("name"),obj.getString("host"), obj.getInt("port"), new Date(obj.getLong("heartbeat")), memberId);
    		member.setFailedCount(obj.getInt("failedCount"));
    		GossipService.debug("parse sync json obj: " + member.toString());
    		members.add(member);
    	}
    	if(members.size()>0)
    		return members;
    	else
    	{
    		GossipService.error("no sync members parsed.");
    		return null;
    	}
    }
}
